<template>
  <div class="message" :class="isSelf ? 'self' : 'opposite'"
       v-if="(type === 'videoCall' && callState !== null) || type !== 'videoCall'">
    <div class="avatarBox cp">
      <avatar
        :showuserinfo="msgId + '&' + (id ? id : tools.getUserId())"
        :id="id ? id : tools.getUserId()"
        :imgID="imgID"
      ></avatar>
    </div>
    <div class="cont" @contextmenu.prevent="showRightList($event)"
    >
      <div class="memberName" v-if="current_contact.id_type === 2 && !isSelf">
        {{ memberNmae }}
      </div>
      <img
        class="sending"
        v-if="isSelf && reqId"
        src="@/assets/message/sending.gif"
      />
      <div v-if="type === 'words'" class="words">
        {{ msg }}
      </div>
      <div v-if="type === 'pic'" class="pic">
        <img
          :src="imgSrc"
          alt=""
          title="查看原图"
          class="cp"
          @click="showOriginImage"
        />
        <div class="picError cp" v-if="sendImgError" @click="reSendImg">!</div>
      </div>
      <div
        v-if="type === 'file'"
        class="file flex-start cp"
      >
        <img :src="fileName | imgSrc" alt=""/>
        <div class="desc">
          <div class="name">{{ fileName }}</div>
          <div class="size">{{ fileSize | fileSize }}</div>
        </div>
      </div>
      <div v-if="type === 'voice'" class="voice cp" @click="playVoice">
        <div v-if="isSelf">
          <div class="time">12"</div>
          <div class="audio"></div>
        </div>
        <div v-else>
          <div class="speaker">
            <img
              src="@/assets/message/voice.gif"
              alt=""
              v-if="amr && amr._isPlaying && amrID === msgId"
            />
            <img src="@/assets/message/voice.png" alt="" v-else/>
          </div>
          <div class="audio" ref="audio"></div>
          <div class="time">{{ voiceLength }}"</div>
          <i class="listened" v-show="!listened"></i>
        </div>
      </div>
      <div v-if="type === 'videoCall'" class="videoCall cp" @click="videoCall">
        <img
          :src="isSelf ? require('@/assets/cfRoom/images/onVideo.png') : require('@/assets/cfRoom/images/onVideoGrey.png')"
          alt="">
        <span v-if="callState !== 5">{{ isSelf ? (callState === 1 || callState === 3 ? '' : '对方') : (callState === 2 ? '' : '对方') }}{{ callState | videoCallStateDealer }}</span>
        <span v-else>视频通话时长{{ durationTime }}</span>
      </div>
      <div v-if="type === 'notice'" class="notice cp" @click="joinCf">
        <div class="hdBox flex-between">
          <div class="noticetype flex-start">
            <img
              :src="
                require('@/assets/message/' + (noticeType === 1
                  ? 'meeting'
                  : 'meetingover') + '.png')
              "
              alt=""
            />
            <div class="typetit">视频会议</div>
          </div>
          <div class="state" :class="noticeTypeDesc.className">
            {{ noticeTypeDesc.name }}
          </div>
        </div>
        <div class="noticeInfo">
          <div class="tit">{{ cfName }}</div>
          <div class="host">主持人：{{ cfSponsorName }}</div>
          <div class="joinCfNum">参会人：{{ cfPlanParticipantCount }}人</div>
        </div>
      </div>
    </div>
    <ul class="rightMsgList" v-if="ifShowMsgRightList === msgId && type !== 'notice' && type !== 'videoCall'" ref="rightMsgList">
      <li v-for="item in rightList" :key="item.id" class="singleWrap" @click="operates(item.fnName)" :downloadFile="item.fnName === 'download' ? 'downloadFile': ''">
        <img :src="item.icon" alt="" :downloadFile="item.fnName === 'download' ? 'downloadFile': ''">
        <span :downloadFile="item.fnName === 'download' ? 'downloadFile': ''">{{ item.name }}</span>
      </li>
    </ul>
  </div>
</template>

<script>
import { sendSock } from '@/utils/socketSend'

export default {
  props: {
    id: {
      require: Number
    },
    isSelf: {
      require: Boolean
    },
    type: {
      require: String
    },
    msg: {
      require: String
    },
    imgSrc: {
      require: Object
    },
    imgWidth: {
      require: Number
    },
    imgHeight: {
      require: Number
    },
    fileName: {
      require: String
    },
    fileSize: {
      require: String
    },
    fileId: {
      require: String | Number
    },
    msgId: {
      require: String
    },
    // 消息时间
    timestamp: {
      require: Number
    },
    // 语音的blob文件
    voiceFile: {
      require: Object
    },
    // 语音是否已经听过
    listened: {
      require: Boolean
    },
    // 语音长度
    voiceLength: {
      require: Number
    },
    // 视频通话类型
    callState: {
      require: Number
    },
    // 视频通话通话时长
    duration: {
      require: Number
    },
    // req_Id
    reqId: {
      require: Number
    },
    // 消息通知的类型 0::未开始 1:会议中  2:已结束
    noticeType: {
      require: String | Number
    },
    // 消息通知的会议名称
    cfName: {
      require: String
    },
    // 消息通知的会议主持人
    cfSponsorName: {
      require: String
    },
    // 消息通知的计划参会人数量
    cfPlanParticipantCount: {
      require: Number
    }
  },
  data () {
    return {
      sendImgError: false,
      // 右键列表
      rightList: []
    }
  },
  computed: {
    current_contact () {
      return this.$store.state.chatInformation.current_contact
    },
    // 成员名称
    memberNmae () {
      const member = this.$store.state.chatInformation.userList[this.id]
      return member.remarks ? member.remarks : member.user_name
    },
    // amr对象
    amr () {
      return this.$store.state.message.amr
    },
    // amr对象对应的msgID
    amrID () {
      return this.$store.state.message.amrID
    },
    // 头像的imgID
    imgID () {
      if (this.type === 'notice') {
        return this.id
      } else {
        return this.$store.state.chatInformation.userList[
          this.id || this.tools.getUserId()
        ].user_img_id
      }
    },
    // 会议消息通知补充信息
    noticeTypeDesc () {
      let className = ''
      let name = ''
      switch (this.noticeType) {
        case 0:
          className = 'beforeStart'
          name = '待开始'
          break
        case 1:
          className = 'meeting'
          name = '会议中'
          break
        case 2:
          className = 'afterMeeting'
          name = '已结束'
          break
      }
      return { className, name }
    },
    // 视频通话时长转换
    durationTime () {
      const mins = String(Math.floor(this.duration / 60))
      let secs = this.duration % 60
      secs = secs >= 10 ? String(secs) : ('0' + secs)
      return mins + ':' + secs
    },
    // 右键菜单的显示隐藏
    ifShowMsgRightList () {
      return this.$store.state.message.ifShowMsgRightList
    },
    // 右键菜单
    operateMenu () {
      return this.$store.state.message.operateMenu
    }
  },
  filters: {
    videoCallStateDealer: (val) => {
      let text = ''
      switch (val) {
        case 1: {
          text = '已取消'
          break
        }
        case 2: {
          text = '已拒绝'
          break
        }
        case 3: {
          text = '已取消'
          break
        }
        case 5: {
          text = '视频通话时长'
          break
        }
      }
      return text
    }
  },
  mounted () {
    if (this.type === 'voice') {
      this.computedVoiceLength()
    }
  },
  methods: {
    reSendImg () {
      // 重新发送图片
    },
    showOriginImage () {
      // 查看原图
      this.$store.commit('common/set_originImage', {
        width: this.imgWidth,
        height: this.imgHeight,
        src: this.imgSrc
      })
      this.$store.commit('common/set_ifShowOriginDialog')
    },
    // 播放/停止语音
    playVoice () {
      if (!this.listened) {
        this.$store.commit('chatInformation/set_userMessage_listened', {
          id: this.current_contact.id,
          idType: this.current_contact.id_type,
          msgID: this.msgId
        })
      }
      this.$store.commit('message/set_amr', {
        blob: this.voiceFile,
        msgID: this.msgId
      })
      this.$store.commit('message/set_amrID', this.msgId)
    },
    // 计算语音需要的长度
    computedVoiceLength () {
      this.$refs.audio.style.width = this.voiceLength * 0.03 + 'rem'
    },
    // 发起语音通话
    videoCall () {
      if (!this.$store.state.common.ifShowVideoInvitation) {
        sendSock({
          type: '2.1.1',
          body: {
            id_type: 2, // 此处应该是call_type，借用id_type的规则
            id: this.current_contact.id,
            timestamp: +new Date()
          }
        })
        // 设置消息reqID
        this.$store.commit('socket/set_operationReqId', 'sendCallReqId')
      }
    },
    // 加入会议
    joinCf () {
      switch (this.noticeType) {
        case 0: {
          this.$message({
            type: 'info',
            message: '会议待开始'
          })
          break
        }
        case 1: {
          const settings = JSON.parse(JSON.stringify(this.$store.state.user.generalSettings))
          // 会议继承设置
          this.$store.commit('conferenceRoom/set_conferenceSettings', settings)
          sendSock({
            type: '4.1.1',
            body: {
              voiced: settings.voiced,
              camera: settings.camera,
              cf_join_type: 0,
              cf_id: this.msgId
            }
          })
          this.$store.commit('socket/set_operationReqId', 'joinConferenceReqId')
          break
        }
        case 2: {
          this.$message({
            type: 'info',
            message: '会议已结束'
          })
        }
      }
    },
    // 查看右键菜单
    showRightList (e) {
      if (this.type !== 'notice' && this.type !== 'videoCall') {
        this.$store.commit('message/set_ifShowMsgRightList', this.msgId)
        this.$nextTick(() => {
          const rightList = this.$refs.rightMsgList
          if (e.clientX + this.$refs.rightMsgList.clientWidth <= document.body.clientWidth) {
            rightList.style.left = e.clientX + 'px'
          } else {
            rightList.style.left = e.clientX - this.$refs.rightMsgList.clientWidth + 'px'
          }
          rightList.style.top = e.clientY + 'px'
          this.rightList = this.operateMenu.filter(item => item.types.some(it => it === this.type))
          if (!this.isSelf || (this.isSelf && new Date() - this.timestamp > 120000)) {
            this.rightList = this.rightList.filter(item => item.id !== 1)
          }
        })
      }
    },
    // 点击右键菜单项
    operates (fnName) {
      this[fnName]()
    },
    // 转发
    forward () {
      console.log('转发')
    },
    // 撤回
    withdraw () {
      console.log('撤回')
      this.$store.commit('message/set_withdrawInfo', {
        id_type: this.current_contact.id_type,
        id: this.current_contact.id,
        msg_id: this.msgId,
        isSelf: true
      })
      sendSock({
        type: '5.2.6',
        body: {
          id_type: this.current_contact.id_type,
          id: this.current_contact.id,
          msg_id: this.msgId
        }
      })
      this.$store.commit('socket/set_operationReqId', 'withdrawReqId')
    },
    // 下载
    download () {
      this.$store
        .dispatch('file/downloadFile', {
          fileType: this.current_contact.id_type === 1 ? 4 : 5,
          fileID: this.fileId,
          other: this.current_contact.id
        })
        .then(res => {
          this.tools.download(res, this.fileName)
        })
    },
    // 收藏
    collect () {
      console.log('收藏')
      console.log(this.fileId)
      this.$store.dispatch('filePage/addFiles', this.fileId).then(res => {
        if (res.data && res.data.code === 200) {
          this.$message.warning('已收藏至我的文件')
        }
      })
    },
    // 删除
    delete () {
      this.$store.commit('chatInformation/set_deleteMsgID', this.msgId)
    }
  }
}
</script>

<style scoped lang="scss">
.message {
  margin-bottom: 24px;
  overflow: hidden;

  .avatarBox {
    width: 36px;
    height: 36px;

    img {
      height: 100%;
      width: 100%;
    }
  }

  .cont {
    max-width: 40%;
    position: relative;

    .sending {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      left: -40px;
      width: 24px;
      height: 24px;
    }

    .memberName {
      height: 17px;
      font-size: 12px;
      font-family: PingFangSC, PingFangSC-Regular;
      font-weight: 400;
      color: #5f7196;
      line-height: 17px;
      margin-bottom: 8px;
      white-space: nowrap;
    }

    .words {
      word-break: break-word;
      padding: 10px 12px;
      opacity: 1;
      border-radius: 0px;
      opacity: 1;
      font-size: 14px;
      font-family: PingFangSC, PingFangSC-Regular;
      font-weight: 400;
      color: #0D172C;
      line-height: 20px;
    }

    .pic {
      position: relative;

      img {
        max-width: 240px;
        vertical-align: middle;
      }

      .picError {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 16px;
        height: 16px;
        text-align: center;
        line-height: 16px;
        font-size: 12px;
        color: #fff;
        background: #ff3e6d;
        border-radius: 50%;
      }
    }

    .file {
      width: 320px;
      padding: 12px 16px;
      background-color: #fff;
      border-radius: 0px 12px 12px 12px;

      img {
        height: 40px;
      }

      .desc {
        .name {
          max-width: 250px;
          height: 20px;
          opacity: 1;
          font-size: 14px;
          font-family: PingFangSC, PingFangSC-Regular;
          font-weight: 400;
          color: #0D172C;
          line-height: 20px;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          word-break: break-all;
        }

        .size {
          margin-top: 3px;
          height: 17px;
          opacity: 1;
          font-size: 12px;
          font-family: PingFangSC, PingFangSC-Regular;
          font-weight: 400;
          color: #5f7196;
          line-height: 17px;
        }
      }
    }

    .voice {
      height: 40px;
      position: relative;
      font-size: 0;

      .speaker {
        line-height: 40px;
        width: 44px;
        height: 40px;
        text-align: center;
        display: inline-block;
        vertical-align: middle;

        img {
          vertical-align: middle;
          width: 18px;
          height: 18px;
        }
      }

      .audio {
        height: 40px;
        display: inline-block;
        vertical-align: middle;
      }

      .time {
        display: inline-block;
        vertical-align: middle;
        text-align: center;
        width: 44px;
        height: 40px;
        line-height: 40px;
        color: #9eaac4;
        font-size: 14px;
      }
    }

    .videoCall {
      padding: 10px 12px;
      font-size: 14px;
      font-weight: 400;
      color: #0D172C;
      line-height: 20px;

      img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 10px;
      }

      span {
        vertical-align: middle;
      }
    }

    .notice {
      width: 360px;
      opacity: 1;
      background: #ffffff;
      border-radius: 4px;
      padding: 0 12px 12px;

      .hdBox {
        border-bottom: 1px solid #EBEDF3;

        .noticetype {
          height: 48px;

          img {
            width: 24px;
            height: 24px;
          }

          .typetit {
            margin-left: 12px;
            height: 17px;
            font-size: 12px;
            font-family: PingFangSC, PingFangSC-Regular;
            font-weight: 400;
            text-align: left;
            color: #5f7196;
            line-height: 17px;
          }
        }

        .state {
          height: 17px;
          font-size: 12px;
          font-family: PingFangSC, PingFangSC-Regular;
          font-weight: 400;
          line-height: 17px;
        }

        .beforeStart {
          color: #ffb000;

          &::before {
            content: "●";
            font-size: 12px;
            color: #ffb000;
          }
        }

        .meeting {
          color: #1ac47c;

          &::before {
            content: "●";
            font-size: 12px;
            color: #1ac47c;
          }
        }

        .afterMeeting {
          color: #9eaac4;

          &::before {
            content: "●";
            font-size: 12px;
            color: #9eaac4;
          }
        }
      }

      .noticeInfo {
        margin-top: 12px;

        .tit {
          height: 20px;
          font-size: 14px;
          font-family: PingFangSC, PingFangSC-Medium;
          font-weight: 500;
          color: #0D172C;
          line-height: 20px;
        }

        .host, .joinCfNum {
          margin-top: 8px;
          height: 17px;
          font-size: 12px;
          font-family: PingFangSC, PingFangSC-Regular;
          color: #5f7196;
          line-height: 17px;
        }
      }
    }
  }

  .opposite {
    .avatarBox {
      float: left;
    }

    .cont {
      margin-left: 12px;
      float: left;

      .words {
        background: #ffffff;
        color: #0D172C;
        border-radius: 0px 12px 12px 12px;
      }

      .pic {
        .picError {
          right: -32px;
        }
      }

      .voice {
        background-color: #fff;
        border-radius: 0 12px 12px 12px;

        .listened {
          position: absolute;
          right: -8px;
          width: 6px;
          height: 6px;
          background-color: #ff3e6d;
          top: 50%;
          transform: translateY(-50%);
          border-radius: 3px;
        }
      }

      .videoCall {
        background-color: #fff;
        border-radius: 0px 12px 12px 12px;

        span {
        }
      }
    }
  }

  .self {
    .cont {
      margin-right: 12px;
      float: right;

      .words, .videoCall {
        background-color: #304eec;
        color: #ffffff;
        border-radius: 12px 0px 12px 12px;
      }

      .pic {
        .picError {
          left: -32px;
        }
      }

      .voice {
        background-color: #304eec;
        border-radius: 12px 0 12px 12px;
      }
    }

    .avatarBox {
      float: right;
    }
  }
  .rightMsgList {
    padding: 4px;
    background-color: #fff;
    border-radius: 2px;
    box-shadow: 0px 4px 16px 0px rgba(13,23,44,0.10);
    position: fixed;
    z-index: 999;
    width: 128px;

    li {
      width: 120px;
      height: 32px;
      line-height: 32px;
      color: #0D172C;
      padding-left: 16px;

      &:hover {
        background-color: rgba(48,78,236,0.04);
      }

      img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 8px;
      }

      span {
        font-size: 12px;
        vertical-align: middle;
      }
    }
  }
}
</style>
